package com.system.shiro.credentials;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.filter.authc.AuthenticationFilter;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.common.servlet.ValidateCodeServlet;
import com.system.service.ISysLoginService;
import com.system.service.ISysStaffService;
import com.system.vo.SysLoginLogVO;
import com.system.vo.SysRoleVO;
import com.system.vo.SysStaffVO;

public class MyFormAuthrnticationFilter extends FormAuthenticationFilter {
		
	private static final Logger logger = LoggerFactory.getLogger(MyFormAuthrnticationFilter.class);
	@Resource
	private ISysStaffService staffService;
	 @Resource
	private ISysLoginService loginService;
	 
	protected boolean onAccessDenied(ServletRequest request,
			ServletResponse response) throws Exception {

		HttpServletRequest res = (HttpServletRequest) request;
		String string = res.getParameter("j_random");
		if (string != null) {
			boolean flag = ValidateCodeServlet.validate(res, string);
			if (!flag){// 验证不成功，阻止进入不在登录认证
				request.setAttribute("shiroLoginFailure","randomCodeError");  
				return true;
			}
		}
		return super.onAccessDenied(request, response);
	}	
	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
		// 1.用户存入session
		Session session = subject.getSession();
		String staffId = (String) token.getPrincipal();
		String staffName=(String) token.getPrincipal();
		SysStaffVO staff = staffService.findAccountByName(staffName);
	    String roleId = null;
	    SysLoginLogVO loginVo = loginService.getLoginLogVo(staff.getStaffId());
			if(null == loginVo){
				roleId=staffService.findRolesIdByStaffId(staff.getStaffId());
				if (null == roleId){
					logger.info("用户：{}没有系统相关角色", staffName);
					request.setAttribute("shiroLoginFailure","noRoleInThisSystem");  
					return true;
				}
			}else{
				roleId = loginVo.getRoleId();
			}
		SysRoleVO userRole = staffService.findRoleById(roleId);
		List<SysRoleVO> list = staffService.findRolesByUserId(staff.getStaffId());
		if (userRole != null) {
			Set<String> roles =new HashSet<String>();
			roles.add(userRole.getRoleName());
		    staff.setRole(userRole);
		    staff.setRoles(roles);
		    staff.setRoleId(userRole.getRoleId());
		    staff.setStaffRoles(list);
		}
		session.setAttribute("user", staff);
		
		// 2.跳转页面
		String fallbackUrl = this.getSuccessUrl();
		String successUrl = null;
		SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);
		if (savedRequest != null && savedRequest.getMethod().equalsIgnoreCase(AccessControlFilter.GET_METHOD)) {
			successUrl = savedRequest.getRequestUrl();
		}
		if (!StringUtils.isEmpty(fallbackUrl) && !AuthenticationFilter.DEFAULT_SUCCESS_URL.equals(fallbackUrl)) {
			successUrl = ((HttpServletRequest) request).getContextPath() + fallbackUrl;
		}
		if (successUrl == null) {
			successUrl = this.getSuccessUrl();
		}
		if (successUrl == null) {
			throw new IllegalStateException(
					"SuccessURLnotavailableviasavedrequestorviathe"
							+ "successUrlFallbackmethodparameter.Oneofthesemustbenon-nullfor"
							+ "issueSuccessRedirect()towork.");
		}
		WebUtils.issueRedirect(request, response, successUrl,null,false);
		return false;
	}

	@Override
	protected AuthenticationToken createToken(ServletRequest request,
			ServletResponse response) {
		String username = getUsername(request);
		String password = getPassword(request);
		String md5password = encode(password);
		return createToken(username, md5password, request, response);
	}

	// MD5加密
	public String encode(String inStr) {
		String outStr = "";
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] output = Base64.encode(md5.digest(inStr.getBytes("utf-8")));
			outStr = new String(output, "utf-8");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return outStr;
	}

	public static void main(String[]agrs){
		MyFormAuthrnticationFilter ss = new MyFormAuthrnticationFilter();
		String admin = ss.encode("admin");
		System.out.println(admin);
	}
	
}
